package com.jingdianjichi.auth.domain.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.jingdianjichi.auth.common.enums.AuthUserStatusEnum;
import com.jingdianjichi.auth.common.enums.IsDeleteFlagEnum;
import com.jingdianjichi.auth.domain.convert.AuthPermissionBOConvert;
import com.jingdianjichi.auth.domain.entity.AuthPermissionBO;
import com.jingdianjichi.auth.domain.redis.RedisUtil;
import com.jingdianjichi.auth.domain.service.AuthPermissionDomainService;
import com.jingdianjichi.basic.entity.AuthPermission;
import com.jingdianjichi.basic.entity.AuthRolePermission;
import com.jingdianjichi.basic.entity.AuthUser;
import com.jingdianjichi.basic.entity.AuthUserRole;
import com.jingdianjichi.basic.mapper.AuthPermissionMapper;
import com.jingdianjichi.basic.service.AuthPermissionService;
import com.jingdianjichi.basic.service.AuthRolePermissionService;
import com.jingdianjichi.basic.service.AuthUserRoleService;
import com.jingdianjichi.basic.service.AuthUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 权限操作服务实现类，对【auth_permission】表进行数据库操作
 * @author WuYimin
 * @description 针对表【auth_permission】的数据库操作Service实现
 * @createDate 2024-02-09 08:49:18
 */
@Service
public class AuthPermissionDomainServiceImpl implements AuthPermissionDomainService{

	@Resource
	private AuthPermissionService authPermissionService; // 注入权限服务

	@Resource
	private AuthUserService authUserService;

	@Resource
	private AuthUserRoleService authUserRoleService;

	@Resource
	private AuthRolePermissionService authRolePermissionService;

	@Resource
	private RedisUtil redisUtil;

	private String authPermissionPrefix = "auth.permission";


	/**
	 * 新增权限
	 * @param authPermissionBO 权限业务对象
	 * @return 操作是否成功
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean add(AuthPermissionBO authPermissionBO) {
		// 将权限业务对象转换为数据库实体对象
		AuthPermission authPermission = AuthPermissionBOConvert.INSTANCE.convertBoToEntity(authPermissionBO);
		// 设置未删除标志
		authPermission.setIsDeleted(IsDeleteFlagEnum.UN_DELETED.getCode());
		// 调用权限服务进行保存
		boolean result = authPermissionService.save(authPermission);
		return result;
	}

	/**
	 * 更新权限
	 * @param authPermissionBO 权限业务对象
	 * @return 操作是否成功
	 */
	@Override
	public Boolean update(AuthPermissionBO authPermissionBO) {
		// 将权限业务对象转换为数据库实体对象
		AuthPermission authPermission = AuthPermissionBOConvert.INSTANCE.convertBoToEntity(authPermissionBO);
		// 创建查询条件
		LambdaQueryWrapper<AuthPermission> lambdaQueryWrapper = new LambdaQueryWrapper<>();
		lambdaQueryWrapper.eq(AuthPermission::getId,authPermission.getId());
		// 调用权限服务进行更新
		boolean result = authPermissionService.update(authPermission, lambdaQueryWrapper);
		return result;
	}

	/**
	 * 删除权限
	 * @param authPermissionBO 权限业务对象
	 * @return 操作是否成功
	 */
	@Override
	public Boolean delete(AuthPermissionBO authPermissionBO) {
		// 将权限业务对象转换为数据库实体对象
		AuthPermission authPermission = AuthPermissionBOConvert.INSTANCE.convertBoToEntity(authPermissionBO);
		// 创建更新条件
		LambdaUpdateWrapper<AuthPermission> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
		lambdaUpdateWrapper.eq(AuthPermission::getId,authPermission.getId())
				.set(AuthPermission::getIsDeleted,IsDeleteFlagEnum.DELETED.getCode());
		// 调用权限服务进行逻辑删除
		boolean result = authPermissionService.update(null, lambdaUpdateWrapper);
		return result;
	}

	/**
	 * 启用/禁用权限
	 * @param authPermissionBO 权限业务对象
	 * @return 操作是否成功
	 */
	@Override
	public Boolean changeStatus(AuthPermissionBO authPermissionBO) {
		// 将权限业务对象转换为数据库实体对象
		AuthPermission authPermission = AuthPermissionBOConvert.INSTANCE.convertBoToEntity(authPermissionBO);
		// 创建更新条件
		LambdaUpdateWrapper<AuthPermission> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
		lambdaUpdateWrapper.eq(AuthPermission::getId,authPermission.getId())
				.set(AuthPermission::getIsDeleted,IsDeleteFlagEnum.DELETED.getCode())
				.set(AuthPermission::getStatus, AuthUserStatusEnum.OPEN.getCode());
		// 调用权限服务进行状态更新
		boolean result = authPermissionService.update(null, lambdaUpdateWrapper);
		return result;
	}

	/**
	 * 查询用户权限
	 * @param userName 用户名
	 * @return 返回一个字符串列表，包含用户的所有权限
	 */
	@Override
	public List<String> getPermission(String userName) {
		// 使用Redis工具类和权限前缀构建存储权限的键
		String permissionKey = redisUtil.buildKey(authPermissionPrefix, userName);
		// 从Redis中获取以该键存储的权限数据
		String permissionValue = redisUtil.get(permissionKey);
		// 检查从Redis获取的权限数据是否为空或者空字符串，如果是，则返回一个空的列表
		if (StringUtils.isBlank(permissionValue)) {
			return Collections.emptyList();
		}
		// 使用Gson将权限数据（JSON格式的字符串）反序列化为权限对象的列表
		List<AuthPermission> permissionList = new Gson().fromJson(permissionValue,
				new TypeToken<List<AuthPermission>>() {
				}.getType());
		// 将权限对象列表转换成权限键的列表（即提取每个权限对象中的权限键）
		List<String> authList = permissionList.stream().map(AuthPermission::getPermissionKey).collect(Collectors.toList());
		// 返回转换后的权限键列表
		return authList;
	}

}
